package com.css.fxfzysx.modules.vaolEngineering.service.impl;

import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.css.fxfzysx.base.response.RestResponse;
import com.css.fxfzysx.constants.FxfzConstants;
import com.css.fxfzysx.constants.YNEnum;
import com.css.fxfzysx.modules.cztDataMange.result.ParsingResult;
import com.css.fxfzysx.modules.lifeline.annotation.ValidationProcessor;
import com.css.fxfzysx.modules.lifeline.entity.newEntity.SmxMainTableEntity;
import com.css.fxfzysx.modules.lifeline.entity.newEntity.SmxRoadEntity;
import com.css.fxfzysx.modules.lifeline.entity.newEntity.SmxVersionEntity;
import com.css.fxfzysx.modules.lifeline.repository.LifelineEngineeringRepository;
import com.css.fxfzysx.modules.lifeline.utils.ShpUtils;
import com.css.fxfzysx.modules.vaolEngineering.entity.CrVulnerabilityEntity;
import com.css.fxfzysx.modules.vaolEngineering.param.update.RoadParam;
import com.css.fxfzysx.modules.vaolEngineering.repository.CarVulnerabilityRepository;
import com.css.fxfzysx.modules.vaolEngineering.service.CarVulnerabilityService;
import com.css.fxfzysx.modules.vaolEngineering.utils.CheckUtil;
import com.css.fxfzysx.modules.vaolEngineering.utils.MainTableUtils;
import com.css.fxfzysx.modules.vaolEngineering.vo.importVo.CrVulnerabilityImportVo;
import com.css.fxfzysx.modules.ysxManagement.entity.DdRatioEntity;
import com.css.fxfzysx.modules.ysxManagement.entity.RdFactorEntity;
import com.css.fxfzysx.modules.ysxManagement.repository.RdFactorRepository;
import com.css.fxfzysx.util.PlatformDateUtils;
import com.css.fxfzysx.util.PlatformObjectUtils;
import com.css.fxfzysx.util.ShpAnalyticUtil;
import com.css.fxfzysx.util.UUIDGenerator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;

@Service
@Slf4j
public class CarVulnerabilityServiceImpl implements CarVulnerabilityService {

    @Autowired
    private CarVulnerabilityRepository carVulnerabilityRepository;

    @Autowired
    private RdFactorRepository rdFactorRepository;

    @Autowired
    private MainTableUtils mainTableUtils;

    @Autowired
    private ShpUtils shpUtils;

    @Autowired
    private LifelineEngineeringRepository lifelineEngineeringRepository;

    @Override
    public SmxRoadEntity getById(String id) {
        return carVulnerabilityRepository.getById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public RestResponse crVulnerability(String versionId, String tableId) {
        try {
            List<SmxRoadEntity> roadList = new ArrayList<>();
            if (PlatformObjectUtils.isNotEmpty(tableId)) {
                SmxRoadEntity entity = carVulnerabilityRepository.getByTableId(tableId);
                roadList.add(entity);
            } else {
                roadList = carVulnerabilityRepository.getByVersionId(versionId);
            }
            List<RdFactorEntity> allRdFactor = rdFactorRepository.getAllRdFactor();
            List<DdRatioEntity> allDdRatio = rdFactorRepository.getAllDdRatio();
            String[] fieldNames = {"基本烈度", "路基土", "场地类别", "地基失效程度", "路基类型", "路基高程H(m)", "设防烈度"};
            AtomicReference<String> message = new AtomicReference<>("");

            roadList.parallelStream().forEach(roadEntity -> {
                StringBuilder rdIds = new StringBuilder();
                StringBuilder ddIds = new StringBuilder();
                HashMap<String, BigDecimal> dataMap = new HashMap<>();
                for (RdFactorEntity it : allRdFactor) {
                    if (it.getDamageFactor().equals("基本烈度")) {
                        if (mainTableUtils.getValueByKey("smxsfld", roadEntity.getIntensity()).equals(it.getCategory())) {
                            dataMap.put("基本烈度", it.getQuantizedValue());
                            rdIds.append(it.getCrdfId()).append(",");
                        }
                    }
                    if (it.getDamageFactor().equals("路基土")) {
                        if (it.getCategory().contains(mainTableUtils.getValueByKey("smxdlljt", roadEntity.getRoadbedSoil()))) {
                            dataMap.put("路基土", it.getQuantizedValue());
                            rdIds.append(it.getCrdfId()).append(",");
                        }
                    }
                    if (it.getDamageFactor().equals("场地类别")) {
                        if (mainTableUtils.getValueByKey("smxcdlb", roadEntity.getSiteSoil()).equals(it.getCategory())) {
                            dataMap.put("场地类别", it.getQuantizedValue());
                            rdIds.append(it.getCrdfId()).append(",");
                        }
                    }
                    if (it.getDamageFactor().equals("地基失效程度")) {
                        if (mainTableUtils.getValueByKey("smxdldjsx", roadEntity.getFoundationFail()).equals(it.getCategory())) {
                            dataMap.put("地基失效程度", it.getQuantizedValue());
                            rdIds.append(it.getCrdfId()).append(",");
                        }
                    }
                    if (it.getDamageFactor().equals("路基类型")) {
                        if (mainTableUtils.getValueByKey("smxdlljlx", roadEntity.getRoadbedType()).equals(it.getCategory())) {
                            dataMap.put("路基类型", it.getQuantizedValue());
                            rdIds.append(it.getCrdfId()).append(",");
                        }
                    }
                    if (it.getDamageFactor().equals("路基高程H(m)")) {
                        String roadbedHigh = "";
                        BigDecimal value = new BigDecimal(roadEntity.getRoadbedHigh());
                        if (value.compareTo(BigDecimal.ONE) <= 0) {
                            roadbedHigh = "H≤1";
                        }
                        if (BigDecimal.ONE.compareTo(value) < 0 && value.compareTo(BigDecimal.valueOf(2)) <= 0) {
                            roadbedHigh = "1<H≤2";
                        }
                        if (BigDecimal.valueOf(2).compareTo(value) < 0 && value.compareTo(BigDecimal.valueOf(3)) <= 0) {
                            roadbedHigh = "1<H≤2";
                        }
                        if (BigDecimal.valueOf(3).compareTo(value) < 0) {
                            roadbedHigh = "3<H";
                        }
                        if (roadbedHigh.equals(it.getCategory())) {
                            dataMap.put("路基高程H(m)", it.getQuantizedValue());
                            rdIds.append(it.getCrdfId()).append(",");
                        }
                    }
                    if (it.getDamageFactor().equals("设防烈度")) {
                        if (mainTableUtils.getValueByKey("smxdlsfqk", roadEntity.getFortification()).equals(it.getCategory())) {
                            dataMap.put("设防烈度", it.getQuantizedValue());
                            rdIds.append(it.getCrdfId());
                        }
                    }
                }
                if (!verificationParameters(dataMap, fieldNames).equals("ok")) {
                    message.set(verificationParameters(dataMap, fieldNames));
                    return;
                }
                Collection<BigDecimal> values = dataMap.values();
                BigDecimal reduce = values.stream().reduce(new BigDecimal(1), (a, b) -> a.multiply(b));
                BigDecimal multiply = reduce.multiply(new BigDecimal(0.2));
                BigDecimal ind = multiply.subtract(new BigDecimal(0.1)).setScale(3, BigDecimal.ROUND_HALF_UP);
                roadEntity.setUbInd(ind);

                for (DdRatioEntity entity : allDdRatio) {
                    if (entity.getBasicIntensity().equals(mainTableUtils.getValueByKey("smxsfld", roadEntity.getIntensity()) + "度")) {
                        roadEntity.setOi(new BigDecimal(entity.getDispersedRatio()));
                        ddIds.append(entity.getCddrId());
                    }
                }
                BigDecimal result1 = getProbability(BigDecimal.valueOf(0.2), BigDecimal.valueOf(0), ind).setScale(3, BigDecimal.ROUND_HALF_UP);
                roadEntity.setP02(result1);
                BigDecimal result2 = getProbability(BigDecimal.valueOf(0.4), BigDecimal.valueOf(0.2), ind).setScale(3, BigDecimal.ROUND_HALF_UP);
                roadEntity.setP24(result2);
                BigDecimal result3 = getProbability(BigDecimal.valueOf(0.6), BigDecimal.valueOf(0.4), ind).setScale(3, BigDecimal.ROUND_HALF_UP);
                roadEntity.setP46(result3);
                BigDecimal result4 = getProbability(BigDecimal.valueOf(0.8), BigDecimal.valueOf(0.6), ind).setScale(3, BigDecimal.ROUND_HALF_UP);
                roadEntity.setP68(result4);
                BigDecimal result5 = getProbability(BigDecimal.valueOf(1.0), BigDecimal.valueOf(0.8), ind).setScale(5, BigDecimal.ROUND_HALF_UP);
                roadEntity.setP810(result5);

                BigDecimal probability1 = getProbabilityValue(result1, result2, result3, result4, result5);
                BigDecimal probability2 = getProbabilityValue(result2, result1, result3, result4, result5);
                BigDecimal probability3 = getProbabilityValue(result3, result1, result2, result4, result5);
                BigDecimal probability4 = getProbabilityValue(result4, result1, result2, result3, result5);
                BigDecimal probability5 = getProbabilityValue(result5, result1, result2, result3, result4);
                roadEntity.setBasicIntact(probability1);
                roadEntity.setSlightDamage(probability2);
                roadEntity.setModerateDamage(probability3);
                roadEntity.setBadlyDamaged(probability4);
                roadEntity.setDestroy(probability5.setScale(2, RoundingMode.HALF_UP));

                ArrayList<BigDecimal> list = new ArrayList<>();
                list.add(probability1);
                list.add(probability2);
                list.add(probability3);
                list.add(probability4);
                list.add(probability5);
                BigDecimal bigDecimal = list.stream().reduce(BigDecimal::max).get();


                if (bigDecimal.compareTo(probability1) == 0) {
                    roadEntity.setDestructiveState("基本完好");
                }
                if (bigDecimal.compareTo(probability2) == 0) {
                    roadEntity.setDestructiveState("轻微破坏");
                }
                if (bigDecimal.compareTo(probability3) == 0) {
                    roadEntity.setDestructiveState("中等破坏");
                }
                if (bigDecimal.compareTo(probability4) == 0) {
                    roadEntity.setDestructiveState("严重破坏");
                }
                if (bigDecimal.compareTo(probability5) == 0) {
                    roadEntity.setDestructiveState("毁坏");
                }
                roadEntity.setDestructiveStateCorrect(roadEntity.getDestructiveState());
                getOtherIntensities(allRdFactor, dataMap, allDdRatio, roadEntity);
                carVulnerabilityRepository.saveRoadResult(roadEntity);
                mainTableUtils.updateModelBaseIds(rdIds.toString(), ddIds.toString(), roadEntity.getTableId());
                mainTableUtils.updateCalculationStatus(roadEntity.getTableId(),roadEntity.getDisasterRate6State(),
                        roadEntity.getDisasterRate7State(),roadEntity.getDisasterRate8State(),roadEntity.getDisasterRate9State(),roadEntity.getDisasterRate10State(), 1);
            });
            mainTableUtils.updateVersionCalculationStatus(versionId, 0);
            if (PlatformObjectUtils.isNotEmpty(message.get())) {
                return RestResponse.fail(message.get());
            }
            return RestResponse.succeed("计算成功!");
        } catch (Exception e) {
            log.error("get crVulnerability error:{}", e.getMessage(), e);
            return RestResponse.fail("数据异常,计算失败!");
        }
    }

    private void getOtherIntensities(List<RdFactorEntity> allRdFactor, HashMap<String, BigDecimal> dataMap, List<DdRatioEntity> allDdRatio, SmxRoadEntity roadEntity) {
        ArrayList<String> fileNameList = new ArrayList<>();
        fileNameList.add("Ⅵ");
        fileNameList.add("Ⅶ");
        fileNameList.add("Ⅷ");
        fileNameList.add("Ⅸ");
        fileNameList.add("Ⅹ");

        fileNameList.parallelStream().forEach(fieldName -> {
            for (RdFactorEntity it : allRdFactor) {
                if (fieldName.equals(it.getCategory())) {
                    dataMap.put("基本烈度", it.getQuantizedValue());
                }
            }
            Collection<BigDecimal> values = dataMap.values();
            BigDecimal reduce = values.stream().reduce(new BigDecimal(1), (a, b) -> a.multiply(b));
            BigDecimal multiply = reduce.multiply(new BigDecimal(0.2));
            BigDecimal ind = multiply.subtract(new BigDecimal(0.1)).setScale(3, BigDecimal.ROUND_HALF_UP);

            for (DdRatioEntity entity : allDdRatio) {
                if (entity.getBasicIntensity().equals(roadEntity.getIntensity() + "度")) {
                    roadEntity.setOi(new BigDecimal(entity.getDispersedRatio()));
                }
            }
            BigDecimal result1 = getProbability(BigDecimal.valueOf(0.2), BigDecimal.valueOf(0), ind).setScale(3, BigDecimal.ROUND_HALF_UP);
            BigDecimal result2 = getProbability(BigDecimal.valueOf(0.4), BigDecimal.valueOf(0.2), ind).setScale(3, BigDecimal.ROUND_HALF_UP);
            BigDecimal result3 = getProbability(BigDecimal.valueOf(0.6), BigDecimal.valueOf(0.4), ind).setScale(3, BigDecimal.ROUND_HALF_UP);
            BigDecimal result4 = getProbability(BigDecimal.valueOf(0.8), BigDecimal.valueOf(0.6), ind).setScale(3, BigDecimal.ROUND_HALF_UP);
            BigDecimal result5 = getProbability(BigDecimal.valueOf(1.0), BigDecimal.valueOf(0.8), ind).setScale(5, BigDecimal.ROUND_HALF_UP);

            BigDecimal probability1 = getProbabilityValue(result1, result2, result3, result4, result5);
            BigDecimal probability2 = getProbabilityValue(result2, result1, result3, result4, result5);
            BigDecimal probability3 = getProbabilityValue(result3, result1, result2, result4, result5);
            BigDecimal probability4 = getProbabilityValue(result4, result1, result2, result3, result5);
            BigDecimal probability5 = getProbabilityValue(result5, result1, result2, result3, result4);

            ArrayList<BigDecimal> list = new ArrayList<>();
            list.add(probability1);
            list.add(probability2);
            list.add(probability3);
            list.add(probability4);
            list.add(probability5);
            BigDecimal bigDecimal = list.stream().reduce(BigDecimal::max).get();

            String destructiveState = "";
            if (bigDecimal.compareTo(probability1) == 0) {
                destructiveState = "基本完好";
            }
            if (bigDecimal.compareTo(probability2) == 0) {
                destructiveState = "轻微破坏";
            }
            if (bigDecimal.compareTo(probability3) == 0) {
                destructiveState = "中等破坏";
            }
            if (bigDecimal.compareTo(probability4) == 0) {
                destructiveState = "严重破坏";
            }
            if (bigDecimal.compareTo(probability5) == 0) {
                destructiveState = "毁坏";
            }

            switch (fieldName) {
                case "Ⅵ":
                    roadEntity.setDisasterRate6State(destructiveState);
                    roadEntity.setDisasterRate6StateCorrect(destructiveState);
                    break;
                case "Ⅶ":
                    roadEntity.setDisasterRate7State(destructiveState);
                    roadEntity.setDisasterRate7StateCorrect(destructiveState);
                    break;
                case "Ⅷ":
                    roadEntity.setDisasterRate8State(destructiveState);
                    roadEntity.setDisasterRate8StateCorrect(destructiveState);
                    break;
                case "Ⅸ":
                    roadEntity.setDisasterRate9State(destructiveState);
                    roadEntity.setDisasterRate9StateCorrect(destructiveState);
                    break;
                case "Ⅹ":
                    roadEntity.setDisasterRate10State(destructiveState);
                    roadEntity.setDisasterRate10StateCorrect(destructiveState);
            }
        });
    }

    private static String verificationParameters(HashMap<String, BigDecimal> dataMap, String[] fieldNames) {
        String message = "";
        for (int i = 0; i < fieldNames.length; i++) {
            if (!dataMap.containsKey(fieldNames[i])) {
                return message = "失败,请在 【道路路基路面震害因子量化取值表】 中维护 {" + fieldNames[i] + "} 信息";
            }
        }
        return message = "ok";
    }

    private static BigDecimal getProbabilityValue(BigDecimal a, BigDecimal b, BigDecimal c, BigDecimal d, BigDecimal e) {
        return a.divide(a.add(b).add(c).add(d).add(e), 3, BigDecimal.ROUND_HALF_UP);
    }


    private static BigDecimal getProbability(BigDecimal a, BigDecimal b, BigDecimal c) {
        BigDecimal value = getValue(new BigDecimal(2).multiply(new BigDecimal(Math.PI)));
        BigDecimal result1 = selfCaculate((a.subtract(c)).divide(new BigDecimal(0.2), 7, BigDecimal.ROUND_HALF_UP));
        BigDecimal result2 = selfCaculate((b.subtract(c)).divide(new BigDecimal(0.2), 7, BigDecimal.ROUND_HALF_UP));
        return value.multiply(result1.subtract(result2));
    }

    /**
     * 开平方根
     *
     * @param value
     * @return
     */
    private static BigDecimal getValue(BigDecimal value) {
        BigDecimal num2 = BigDecimal.valueOf(2);
        int precision = 100;
        MathContext mc = new MathContext(precision, RoundingMode.HALF_UP);
        BigDecimal deviation = value;
        int cnt = 0;
        while (cnt < precision) {
            deviation = (deviation.add(value.divide(deviation, mc))).divide(num2, mc);
            cnt++;
        }
        BigDecimal multiply = deviation.multiply(new BigDecimal(0.2));
        deviation = multiply.setScale(7, BigDecimal.ROUND_HALF_UP);
        return deviation;
    }


    /**
     * 计算fai
     *
     * @param u
     */
    public static BigDecimal selfCaculate(BigDecimal u) {
        BigDecimal ret = new BigDecimal(0);
        if (u.compareTo(new BigDecimal(-3.89)) == -1) {
            return new BigDecimal(0);
        } else if (u.compareTo(new BigDecimal(3.89)) == 1) {
            return new BigDecimal(1);
        }
        BigDecimal temp = new BigDecimal(-3.89);
        while (temp.compareTo(u) != 1) {
            ret = ret.add(new BigDecimal(0.0001).multiply(fx(temp)));
            temp = temp.add(new BigDecimal(0.0001));
        }
        return ret;
    }

    private static BigDecimal fx(BigDecimal x) {
        BigDecimal ret = new BigDecimal(0);
        double a = 1.0 / Math.sqrt(Math.PI * 2);
        a = a * Math.pow(Math.E, -0.5 * Math.pow(Double.valueOf(x.toString()), 2));
        ret = new BigDecimal(a);
        return ret;
    }

    @Override
    public List<CrVulnerabilityEntity> getVulnerabilityById(String id) {
        return carVulnerabilityRepository.getVulnerabilityById(id);
    }

    @Override
    public RestResponse importVulnerability(MultipartFile file) {
        try {
            ExcelReader reader = ExcelUtil.getReader(file.getInputStream());
            List<List<Object>> read = reader.read(1, reader.getRowCount());
            List<Object> title = reader.readRow(0);
            String titleName = "[基本烈度, 路基土, 场地类别, 地基失效程度, 路基类型, 路基高程H(m)]";
            if (!titleName.equals(title.toString())) {
                return RestResponse.fail("导入失败，请检查表头是否改动");
            }
            if (read.size() == 0) {
                return RestResponse.fail("导入失败，表格中无数据");
            }
            //数据校验
            RestResponse rs = CheckUtil.check(1, read.size(), read, titleName);
            if (rs.getCode() != 200) {
                return RestResponse.fail(rs.getMessage());
            }
            ArrayList<CrVulnerabilityImportVo> dataList = new ArrayList<>();
            read.forEach(it -> {
                CrVulnerabilityImportVo entity = new CrVulnerabilityImportVo();
                entity.setBasicIntensity(it.get(0).toString());
                entity.setRoadbedSoil(it.get(1).toString());
                entity.setSite(it.get(2).toString());
                entity.setFoundationFail(it.get(3).toString());
                entity.setRoadbedType(it.get(4).toString());
                entity.setRoadbedElevation(it.get(5).toString());
                dataList.add(entity);
            });
            return RestResponse.succeed(dataList);
        } catch (IOException e) {
            String errorMessage = "数据异常,导入失败!";
            log.error(errorMessage, e);
            return RestResponse.fail(errorMessage);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> uploadRoadShp(String fileIds, String versionId, String userId) throws Exception {
        Map<String, Object> map = new HashMap<>();
        shpUtils.uniformFileName(fileIds);
        ParsingResult shpData = shpUtils.getShpData(fileIds);
        //是否成功
        if (!shpData.getMessage().equals("ok")) {
            map.put("res", false);
            map.put("mess", shpData.getMessage());
        }
        List<List<Object>> shpList = shpData.getShpList();
        List<SmxRoadEntity> roadList = new ArrayList<>();
        for (int i = 0; i < shpList.size(); i++) {
            String id = UUIDGenerator.getUUID();
            List<Object> list = shpList.get(i);
            if (list.size() < 19) {
                return null;
            }
            SmxRoadEntity roadEntity = new SmxRoadEntity();
            roadEntity.setDelFlag(YNEnum.N.toString());
            roadEntity.setId(UUIDGenerator.getUUID());
            roadEntity.setTableId(id);
            roadEntity.setCreateUser(userId);
            roadEntity.setCreateTime(PlatformDateUtils.getCurrentDate());

            if (!PlatformObjectUtils.isEmpty(list.get(0))) {
                roadEntity.setGeom(list.get(0).toString());
            }
            if (!PlatformObjectUtils.isEmpty(list.get(1))) {
                roadEntity.setRoadId(ShpAnalyticUtil.getStringVal(list.get(1).toString(), "", false));
            }
            if (!PlatformObjectUtils.isEmpty(list.get(2))) {
                roadEntity.setName(ShpAnalyticUtil.getStringVal(list.get(2).toString(), "", true));
            }
            if (!PlatformObjectUtils.isEmpty(list.get(3))) {
                roadEntity.setGrade(ShpAnalyticUtil.getStringVal(list.get(3).toString(), "", true));
            }
            if (!PlatformObjectUtils.isEmpty(list.get(4))) {
                roadEntity.setStartLongitude(ShpAnalyticUtil.getStringVal(list.get(4).toString(), "", true));
            }
            if (!PlatformObjectUtils.isEmpty(list.get(5))) {
                roadEntity.setStartLatitude(ShpAnalyticUtil.getStringVal(list.get(5).toString(), "", true));
            }
            if (!PlatformObjectUtils.isEmpty(list.get(6))) {
                roadEntity.setEndLongitude(ShpAnalyticUtil.getStringVal(list.get(6).toString(), "", true));
            }
            if (!PlatformObjectUtils.isEmpty(list.get(7))) {
                roadEntity.setEndLatitude(ShpAnalyticUtil.getStringVal(list.get(7).toString(), "", true));
            }
            if (!PlatformObjectUtils.isEmpty(list.get(8))) {
                roadEntity.setIntensity(ShpAnalyticUtil.getStringVal(list.get(8).toString(), "", true));
            }
            if (!PlatformObjectUtils.isEmpty(list.get(9))) {
                roadEntity.setRoadbedSoil(ShpAnalyticUtil.getStringVal(list.get(9).toString(), "", true));
            }
            if (!PlatformObjectUtils.isEmpty(list.get(10))) {
                roadEntity.setSiteSoil(ShpAnalyticUtil.getStringVal(list.get(10).toString(), "", true));
            }
            if (!PlatformObjectUtils.isEmpty(list.get(11))) {
                roadEntity.setFortification(ShpAnalyticUtil.getStringVal(list.get(11).toString(), "", true));
            }
            if (!PlatformObjectUtils.isEmpty(list.get(12))) {
                roadEntity.setFoundationFail(ShpAnalyticUtil.getStringVal(list.get(12).toString(), "", true));
            }
            if (!PlatformObjectUtils.isEmpty(list.get(13))) {
                roadEntity.setRoadbedType(ShpAnalyticUtil.getStringVal(list.get(13).toString(), "", true));
            }
            if (!PlatformObjectUtils.isEmpty(list.get(14))) {
                BigDecimal value = new BigDecimal(ShpAnalyticUtil.getStringVal(list.get(14).toString(), "", true));
                String roadbedHigh = "";
                if (value.compareTo(BigDecimal.ONE) <= 0) {
                    roadbedHigh = "H≤1";
                }
                if (BigDecimal.ONE.compareTo(value) < 0 && value.compareTo(BigDecimal.valueOf(2)) <= 0) {
                    roadbedHigh = "1<H≤2";
                }
                if (BigDecimal.valueOf(2).compareTo(value) < 0 && value.compareTo(BigDecimal.valueOf(3)) <= 0) {
                    roadbedHigh = "1<H≤2";
                }
                if (BigDecimal.valueOf(3).compareTo(value) < 0) {
                    roadbedHigh = "3<H";
                }
                roadEntity.setRoadbedHigh(mainTableUtils.getKeyByValue("smxdllmgc", roadbedHigh));
            }
            if (!PlatformObjectUtils.isEmpty(list.get(15))) {
                roadEntity.setYear(ShpAnalyticUtil.getIntegerVal(list.get(15).toString(), "", true));
            }
            if (!PlatformObjectUtils.isEmpty(list.get(16))) {
                roadEntity.setCapacity(list.get(16).toString());
            }
            if (!PlatformObjectUtils.isEmpty(list.get(17))) {
                roadEntity.setPavement(list.get(17).toString());
            }
            if (!PlatformObjectUtils.isEmpty(list.get(18))) {
                roadEntity.setLength(list.get(18).toString());
            }
            if (!PlatformObjectUtils.isEmpty(list.get(19))) {
                roadEntity.setWidth(list.get(19).toString());
            }
            if (!PlatformObjectUtils.isEmpty(list.get(20))) {
                roadEntity.setNote(list.get(20).toString());
            }
            if (list.size() > 21 && !PlatformObjectUtils.isEmpty(list.get(21))) {
                roadEntity.setExtends1(list.get(21).toString());
            }
            if (list.size() > 22 && !PlatformObjectUtils.isEmpty(list.get(22))) {
                roadEntity.setExtends2(list.get(22).toString());
            }
            if (list.size() > 23 && !PlatformObjectUtils.isEmpty(list.get(23))) {
                roadEntity.setExtends3(list.get(23).toString());
            }
            if (list.size() > 24 && !PlatformObjectUtils.isEmpty(list.get(24))) {
                roadEntity.setExtends4(list.get(24).toString());
            }
            if (list.size() > 25 && !PlatformObjectUtils.isEmpty(list.get(25))) {
                roadEntity.setExtends5(list.get(25).toString());
            }
            if (list.size() > 26 && !PlatformObjectUtils.isEmpty(list.get(26))) {
                roadEntity.setExtends6(list.get(26).toString());
            }
            if (list.size() > 27 && !PlatformObjectUtils.isEmpty(list.get(27))) {
                roadEntity.setExtends7(list.get(27).toString());
            }
            if (list.size() > 28 && !PlatformObjectUtils.isEmpty(list.get(28))) {
                roadEntity.setExtends8(list.get(28).toString());
            }
            if (list.size() > 29 && !PlatformObjectUtils.isEmpty(list.get(29))) {
                roadEntity.setExtends9(list.get(29).toString());
            }
            if (list.size() > 30 && !PlatformObjectUtils.isEmpty(list.get(30))) {
                roadEntity.setExtends10(list.get(30).toString());
            }
            roadEntity.setVersionId(versionId);
            roadList.add(roadEntity);

            SmxMainTableEntity mainEntity = new SmxMainTableEntity();
            mainEntity.setId(id);
            mainEntity.setCreateUser(userId);
            mainEntity.setYear(roadEntity.getYear());
            mainEntity.setVersionId(versionId);
            mainEntity.setFortification(roadEntity.getFortification());
            mainEntity.setBusinessObject(FxfzConstants.CZT_SMX_DL);
            mainTableUtils.saveMainTable(mainEntity);
        }

        boolean res = false;
        int i = 1;
        for (SmxRoadEntity roadEntity : roadList) {
            roadEntity.setSerialNumber(i);
            res = carVulnerabilityRepository.saveRoad(roadEntity);
            i += 1;
        }
        map.put("res", res);
        return map;
    }

    @Override
    public HashMap<Integer, ArrayList<String>> getDataValidation(String versionId) {
        HashMap<Integer, ArrayList<String>> map = new HashMap<>();
        SmxVersionEntity versionEntity = lifelineEngineeringRepository.getById(versionId);
        if (PlatformObjectUtils.isNotEmpty(versionEntity)) {
            List<SmxRoadEntity> roadList = carVulnerabilityRepository.getByVersionId(versionEntity.getId());
            int i = 1;
            for (SmxRoadEntity roadEntity : roadList) {
                ArrayList<String> list = ValidationProcessor.validate(roadEntity);
                if (list.size() != 0) {
                    map.put(i, list);
                }
                i += 1;
            }
        }
        return map;
    }

    @Override
    public SmxRoadEntity getByTableId(String id) {
        return carVulnerabilityRepository.getByTableId(id);
    }

    @Override
    public void updateRoadById(RoadParam roadParam) {
        carVulnerabilityRepository.updateRoadById(roadParam);
    }

    @Override
    public RestResponse count(RoadParam param) {
        List<RdFactorEntity> allRdFactor = rdFactorRepository.getAllRdFactor();
        List<DdRatioEntity> allDdRatio = rdFactorRepository.getAllDdRatio();
        String[] fieldNames = {"基本烈度", "路基土", "场地类别", "地基失效程度", "路基类型", "路基高程H(m)", "设防烈度"};

        StringBuilder rdIds = new StringBuilder();
        StringBuilder ddIds = new StringBuilder();
        HashMap<String, BigDecimal> dataMap = new HashMap<>();
        for (RdFactorEntity it : allRdFactor) {
            if (it.getDamageFactor().equals("基本烈度")) {
                if (mainTableUtils.getValueByKey("smxsfld", param.getIntensity()).equals(it.getCategory())) {
                    dataMap.put("基本烈度", it.getQuantizedValue());
                    rdIds.append(it.getCrdfId()).append(",");
                }
            }
            if (it.getDamageFactor().equals("路基土")) {
                if (it.getCategory().contains(mainTableUtils.getValueByKey("smxdlljt", param.getRoadbedSoil()))) {
                    dataMap.put("路基土", it.getQuantizedValue());
                    rdIds.append(it.getCrdfId()).append(",");
                }
            }
            if (it.getDamageFactor().equals("场地类别")) {
                if (mainTableUtils.getValueByKey("smxcdlb", param.getSiteSoil()).equals(it.getCategory())) {
                    dataMap.put("场地类别", it.getQuantizedValue());
                    rdIds.append(it.getCrdfId()).append(",");
                }
            }
            if (it.getDamageFactor().equals("地基失效程度")) {
                if (mainTableUtils.getValueByKey("smxdldjsx", param.getFoundationFail()).equals(it.getCategory())) {
                    dataMap.put("地基失效程度", it.getQuantizedValue());
                    rdIds.append(it.getCrdfId()).append(",");
                }
            }
            if (it.getDamageFactor().equals("路基类型")) {
                if (mainTableUtils.getValueByKey("smxdlljlx", param.getRoadbedType()).equals(it.getCategory())) {
                    dataMap.put("路基类型", it.getQuantizedValue());
                    rdIds.append(it.getCrdfId()).append(",");
                }
            }
            if (it.getDamageFactor().equals("路基高程H(m)")) {
                String roadbedHigh = "";
                BigDecimal value = new BigDecimal(param.getRoadbedHigh());
                if (value.compareTo(BigDecimal.ONE) <= 0) {
                    roadbedHigh = "H≤1";
                }
                if (BigDecimal.ONE.compareTo(value) < 0 && value.compareTo(BigDecimal.valueOf(2)) <= 0) {
                    roadbedHigh = "1<H≤2";
                }
                if (BigDecimal.valueOf(2).compareTo(value) < 0 && value.compareTo(BigDecimal.valueOf(3)) <= 0) {
                    roadbedHigh = "1<H≤2";
                }
                if (BigDecimal.valueOf(3).compareTo(value) < 0) {
                    roadbedHigh = "3<H";
                }
                if (roadbedHigh.equals(it.getCategory())) {
                    dataMap.put("路基高程H(m)", it.getQuantizedValue());
                    rdIds.append(it.getCrdfId()).append(",");
                }
            }
            if (it.getDamageFactor().equals("设防烈度")) {
                if (mainTableUtils.getValueByKey("smxdlsfqk", param.getFortification()).equals(it.getCategory())) {
                    dataMap.put("设防烈度", it.getQuantizedValue());
                    rdIds.append(it.getCrdfId());
                }
            }
        }
        if (!verificationParameters(dataMap, fieldNames).equals("ok")) {
            return RestResponse.fail(verificationParameters(dataMap, fieldNames));
        }
        Collection<BigDecimal> values = dataMap.values();
        BigDecimal reduce = values.stream().reduce(new BigDecimal(1), (a, b) -> a.multiply(b));
        BigDecimal multiply = reduce.multiply(new BigDecimal(0.2));
        BigDecimal ind = multiply.subtract(new BigDecimal(0.1)).setScale(3, BigDecimal.ROUND_HALF_UP);
        param.setUbInd(ind);

        for (DdRatioEntity entity : allDdRatio) {
            if (entity.getBasicIntensity().equals(mainTableUtils.getValueByKey("smxsfld", param.getIntensity()) + "度")) {
                param.setOi(new BigDecimal(entity.getDispersedRatio()));
                ddIds.append(entity.getCddrId());
            }
        }
        BigDecimal result1 = getProbability(BigDecimal.valueOf(0.2), BigDecimal.valueOf(0), ind).setScale(3, RoundingMode.HALF_UP);
        param.setP02(result1);
        BigDecimal result2 = getProbability(BigDecimal.valueOf(0.4), BigDecimal.valueOf(0.2), ind).setScale(3, RoundingMode.HALF_UP);
        param.setP24(result2);
        BigDecimal result3 = getProbability(BigDecimal.valueOf(0.6), BigDecimal.valueOf(0.4), ind).setScale(3, RoundingMode.HALF_UP);
        param.setP46(result3);
        BigDecimal result4 = getProbability(BigDecimal.valueOf(0.8), BigDecimal.valueOf(0.6), ind).setScale(3, RoundingMode.HALF_UP);
        param.setP68(result4);
        BigDecimal result5 = getProbability(BigDecimal.valueOf(1.0), BigDecimal.valueOf(0.8), ind).setScale(5, RoundingMode.HALF_UP);
        param.setP810(result5);

        BigDecimal probability1 = getProbabilityValue(result1, result2, result3, result4, result5);
        BigDecimal probability2 = getProbabilityValue(result2, result1, result3, result4, result5);
        BigDecimal probability3 = getProbabilityValue(result3, result1, result2, result4, result5);
        BigDecimal probability4 = getProbabilityValue(result4, result1, result2, result3, result5);
        BigDecimal probability5 = getProbabilityValue(result5, result1, result2, result3, result4);
        param.setBasicIntact(probability1);
        param.setSlightDamage(probability2);
        param.setModerateDamage(probability3);
        param.setBadlyDamaged(probability4);
        param.setDestroy(probability5.setScale(2, RoundingMode.HALF_UP));

        ArrayList<BigDecimal> list = new ArrayList<>();
        list.add(probability1);
        list.add(probability2);
        list.add(probability3);
        list.add(probability4);
        list.add(probability5);
        BigDecimal bigDecimal = list.stream().reduce(BigDecimal::max).get();


        if (bigDecimal.compareTo(probability1) == 0) {
            param.setDestructiveState("基本完好");
        }
        if (bigDecimal.compareTo(probability2) == 0) {
            param.setDestructiveState("轻微破坏");
        }
        if (bigDecimal.compareTo(probability3) == 0) {
            param.setDestructiveState("中等破坏");
        }
        if (bigDecimal.compareTo(probability4) == 0) {
            param.setDestructiveState("严重破坏");
        }
        if (bigDecimal.compareTo(probability5) == 0) {
            param.setDestructiveState("毁坏");
        }
        param.setDestructiveStateCorrect(param.getDestructiveState());
        param.setRdIds(rdIds.toString());
        param.setDdIds(ddIds.toString());
        return RestResponse.succeed(param);
    }
}
